#include "BasicBlock.hpp"
#include "Constant.hpp"
#include "Function.hpp"
#include "IRBuilder.hpp"
#include "Module.hpp"
#include "Type.hpp"

#include <iostream>
#include <memory>

// 定义宏，用于简化常量整数和浮点数的创建
#define CONST_INT(num) ConstantInt::get(num, module.get())
#define CONST_FP(num) ConstantFP::get(num, module.get())

// 生成 main 函数的 IR
void generateMainIR(std::unique_ptr<Module>& module) {
    auto builder = std::unique_ptr<IRBuilder>(new IRBuilder(nullptr, module.get()));
    auto Int32Type = module->get_int32_type();
    auto FloatType = module->get_float_type();

    // 创建 main 函数
    auto mainFun = Function::create(FunctionType::get(Int32Type, {}), "main", module.get());
    if (!mainFun) {
        std::cerr << "Failed to create main function." << std::endl;
        return;
    }

    // 创建入口块
    auto entryBB = BasicBlock::create(module.get(), "entry", mainFun);
    if (!entryBB) {
        std::cerr << "Failed to create entry basic block." << std::endl;
        return;
    }
    builder->set_insert_point(entryBB);

    // 分配变量 a 并初始化为 5.555
    auto aAlloca = builder->create_alloca(FloatType);
    if (!aAlloca) {
        std::cerr << "Failed to create alloca for variable a." << std::endl;
        return;
    }
    builder->create_store(CONST_FP(5.555), aAlloca);

    // 加载变量 a 的值并比较是否大于 1.0
    auto aLoad = builder->create_load(aAlloca);
    if (!aLoad) {
        std::cerr << "Failed to load value of variable a." << std::endl;
        return;
    }
    auto cmp = builder->create_fcmp_gt(aLoad, CONST_FP(1.0));
    if (!cmp) {
        std::cerr << "Failed to create comparison instruction." << std::endl;
        return;
    }

    // 创建 then 和 end 基本块
    auto thenBB = BasicBlock::create(module.get(), "then", mainFun);
    if (!thenBB) {
        std::cerr << "Failed to create then basic block." << std::endl;
        return;
    }
    auto endBB = BasicBlock::create(module.get(), "end", mainFun);
    if (!endBB) {
        std::cerr << "Failed to create end basic block." << std::endl;
        return;
    }

    // 根据比较结果跳转到不同的基本块
    builder->create_cond_br(cmp, thenBB, endBB);

    // 处理 then 块：返回 233
    builder->set_insert_point(thenBB);
    builder->create_ret(CONST_INT(233));

    // 处理 end 块：返回 0
    builder->set_insert_point(endBB);
    builder->create_ret(CONST_INT(0));
}

int main() {
    // 创建模块
    auto module = std::unique_ptr<Module>(new Module());

    // 生成 main 函数的 IR
    generateMainIR(module);

    // 输出生成的 IR 指令
    std::cout << module->print();

    return 0;
}
